package jmine.tec.datadigester.dispatcher;

import java.io.InputStream;
import java.util.concurrent.Callable;

import jmine.tec.datadigester.DataDigesterMessages;
import bancosys.tec.datadigester.DataDigesterController;
import bancosys.tec.datadigester.input.ResetableInputStreamFactory;
import bancosys.tec.exception.BusinessException;
import bancosys.tec.persist.PersistenceController;
import bancosys.tec.persist.audit.AuditManager;
import bancosys.tec.persist.audit.AuditStatus;
import bancosys.tec.security.chinesewall.ChineseWallContext;
import bancosys.tec.security.chinesewall.ChineseWallContextHolder;

/**
 * DataDigester Synchronized Dispatcher
 * 
 * @author vinicius
 */
public class DataDigesterSyncDispatcher implements DataDigesterDispatcher {

    private DataDigesterController dataDigesterController;

    private PersistenceController persistenceController;

    private AuditManager auditManager;

    /**
     * {@inheritDoc}
     */
    public void dispatch(final String code, final String fileName, final InputStream is) {
        ChineseWallContext chineseWallContext = ChineseWallContextHolder.get();
        ChineseWallContextHolder.clear();
        AuditStatus auditStatus = this.auditManager.getThreadAuditStatus();

        this.auditManager.setThreadAuditStatus(AuditStatus.DISABLED);
        try {
            this.persistenceController.executeWithDisabledAuthorization(new Callable<Void>() {
                public Void call() throws Exception {
                    try {
                        DataDigesterSyncDispatcher.this.dataDigesterController.process(code, fileName, is);
                    } finally {
                        ResetableInputStreamFactory.cleanup(is);
                    }
                    return null;
                }
            });
        } catch (Exception e) {
            throw new BusinessException(DataDigesterMessages.GENERIC_DATA_DIGESTER_ERROR.create(), e);
        } finally {
            // Voltar o status da autorização e da auditoria
            ChineseWallContextHolder.set(chineseWallContext);
            this.auditManager.setThreadAuditStatus(auditStatus);
        }
    }

    /**
     * @param dataDigesterController the dataDigesterController to set
     */
    public void setDataDigesterController(DataDigesterController dataDigesterController) {
        this.dataDigesterController = dataDigesterController;
    }

    /**
     * @param persistenceController the persistenceController to set
     */
    public void setPersistenceController(PersistenceController persistenceController) {
        this.persistenceController = persistenceController;
    }

    /**
     * @param auditManager the auditManager to set
     */
    public void setAuditManager(AuditManager auditManager) {
        this.auditManager = auditManager;
    }

}
